package Bind;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
import Annotation.Destino;
import Annotation.Origem;
import Annotation.View;
import java.lang.reflect.Method;
import java.util.HashMap;
import javax.swing.JComboBox;
import javax.swing.JTextField;

/**
 *
 * @author Caio
 */
public final class Mapeia {

    

    public Mapeia() throws Exception {
        
    }

    public void ModelToView(Object model, Object view, HashMap<Method, Method> metodos) throws Exception {
        Class<?> model1 = model.getClass();
        Class<?> view1 = view.getClass();
        for (Method m : model1.getDeclaredMethods()) {
            if (m.isAnnotationPresent(Origem.class)) {
                String nomeModel = m.getAnnotation(Origem.class).nome();
                for (Method n : view1.getDeclaredMethods()) {
                    if (n.isAnnotationPresent(View.class)) {
                        String nomeView = n.getAnnotation(View.class).nome();
                        if (nomeView.equals(nomeModel)) {
                            Object c = n.getReturnType();
                            String cl = c.toString();
                            if (cl.equals("class javax.swing.JTextField")) {
                                metodos.put(m, setTextField(n, view));
                                valida(m, model, view,metodos);
                            } else {
                                metodos.put(m, setCombo(n, view));
                                valida(m, model, view,metodos);
                            }
                        }
                    }
                }
            }
        }
    }

    public void viewToModel(Object model, Object view, HashMap<Method, Method> metodos) throws Exception {
        metodos = new HashMap<>();
        Class<?> model1 = model.getClass();
        Class<?> view1 = view.getClass();
        for (Method m : view1.getDeclaredMethods()) {
            if (m.isAnnotationPresent(View.class)) {
                String nomeView = m.getAnnotation(View.class).nome();
                for (Method n : model1.getDeclaredMethods()) {
                    if (n.isAnnotationPresent(Destino.class)) {
                        String nomeModel = n.getAnnotation(Destino.class).nome();
                        if (nomeView.equals(nomeModel)) {
                            Object c[] = n.getParameterTypes();
                            if (c[0].toString().equals("class java.lang.String")) {
                                metodos.put(n, checaCampo(m, view));
                                n.invoke(model, metodos.get(n).invoke(view,new Object[0]));
                            } else if (c[0].toString().equals("class java.lang.Double")) {
                                metodos.put(n, checaCampo(m, view));
                                n.invoke(model,Double.parseDouble((String) metodos.get(n).invoke(view,new Object[0])));
                            } else if (c[0].toString().equals("class java.lang.Integer")) {
                                metodos.put(n, checaCampo(m, view));
                                n.invoke(model,Integer.parseInt((String) metodos.get(n).invoke(view,new Object[0])));
                            }
                        }
                    }
                }
            }
        }
        System.out.println("");
    }
    
    public Method checaCampo(Method m,Object view) throws Exception{
        Object c = m.getReturnType();
        c=c.toString();
        if (c.equals("class javax.swing.JTextField")){
            return getTextField(m, view);
        }else{
            return getComboField(m, view);
        }
    }

    public Method setCombo(Method a, Object view) throws Exception {
        JComboBox cnb = new JComboBox();
        cnb = (JComboBox) a.invoke(view, new Object[0]);
        Class<?> metodoCombo = new MetodoCombo(cnb).getClass();
        for (Method n : metodoCombo.getDeclaredMethods()) {
            Object retorno = n.getReturnType();
            retorno = retorno.toString();
            if (retorno.equals("void")) {
                return n;
            }
        }
        return null;
    }

    public Method setTextField(Method a, Object view) throws Exception {
        JTextField textfield = new JTextField();
        textfield = (JTextField) a.invoke(view, new Object[0]);
        Class<?> metodoString = new MetodoString(textfield).getClass();
        for (Method n : metodoString.getDeclaredMethods()) {
            Object retorno = n.getReturnType();
            retorno = retorno.toString();
            if (retorno.equals("void")) {
                return n;
            }
        }
        return null;
    }

    public void valida(Method m, Object model, Object view, HashMap<Method, Method> metodos) throws Exception {
        if (m.invoke(model, new Object[0]) != null) {
            metodos.get(m).invoke(view, m.invoke(model, new Object[0]));
        } else {
        }
    }

    public Method getTextField(Method a, Object view) throws Exception {
        JTextField textfield = new JTextField();
        textfield = (JTextField) a.invoke(view, new Object[0]);
        Class<?> metodoString = new MetodoString(textfield).getClass();
        for (Method n : metodoString.getDeclaredMethods()) {
            Object retorno = n.getReturnType().toString();
            if (retorno.equals("class java.lang.String")) {
                return n;
            }
        }
        return null;
    }

    public Method getComboField(Method a, Object view) throws Exception{
        JComboBox combobox = new JComboBox();
        combobox = (JComboBox) a.invoke(view,new Object[0]);
        Class<?> metodoCombo = new MetodoCombo(combobox).getClass();
        for (Method n:metodoCombo.getDeclaredMethods()){
            Object retorno = n.getReturnType().toString();
            if (!retorno.equals("void")){
                return n;
            }
        }
        return null;
    }
    
}
